/*
 * Copyright (C) 2012 www.amsoft.cn
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ab.db.orm;

import java.io.File;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

// TODO: Auto-generated Javadoc
/**
 * © 2012 amsoft.cn 名称：AbSDSQLiteOpenHelper.java 描述：SD卡中保存数据库
 * 
 * @author 还如一梦中
 * @version v1.0
 * @date：2013-7-23 上午9:47:10
 */

public abstract class AbSDSQLiteOpenHelper extends SQLiteOpenHelper {

	/** 数据库名. */
	private final String mName;

	/** 数据库文件保存文件夹全路径. */
	private final String mDir;

	/** 数据库查询的游标工厂. */
	private final SQLiteDatabase.CursorFactory mFactory;

	/** 数据库的新版本号. */
	private final int mNewVersion;

	/** 数据库对象. */
	private SQLiteDatabase mDatabase = null;

	/** 是否已经初始化过. */
	private boolean mIsInitializing = false;

	/**
	 * 初始化一个AbSDSQLiteOpenHelper对象.
	 * 
	 * @param context
	 *            应用Context
	 * @param path
	 *            要放到SDCard下的文件夹路径
	 * @param name
	 *            数据库名
	 * @param factory
	 *            数据库查询的游标工厂
	 * @param version
	 *            数据库的新版本号
	 */
	public AbSDSQLiteOpenHelper(Context context, String dir, String name, CursorFactory factory, int version) {
		super(context, name, factory, version);
		if (version < 1)
			throw new IllegalArgumentException("Version must be >= 1, was " + version);
		mDir = dir;
		mName = name;
		mFactory = factory;
		mNewVersion = version;
	}

	/**
	 * 获取可写权限的数据库对象.
	 * 
	 * @return 数据库对象
	 */
	public synchronized SQLiteDatabase getWritableDatabase() {
		if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
			// 已经获取过
			return mDatabase;
		}
		if (mIsInitializing) {
			throw new IllegalStateException("数据库已被占用getWritableDatabase()");
		}
		boolean success = false;
		SQLiteDatabase db = null;
		try {
			mIsInitializing = true;
			if (mName == null) {
				// 创建一个内存支持SQLite数据库
				db = SQLiteDatabase.create(null);
			} else {
				// 创建一个文件支持SQLite数据库
				String path = mDir + File.separator + mName;
				db = SQLiteDatabase.openOrCreateDatabase(path, mFactory);
			}
			int version = db.getVersion();
			if (version != mNewVersion) {
				db.beginTransaction();
				try {
					if (version == 0) {
						onCreate(db);
					} else {
						onUpgrade(db, version, mNewVersion);
					}
					db.setVersion(mNewVersion);
					db.setTransactionSuccessful();
				} finally {
					db.endTransaction();
				}
			}
			onOpen(db);
			success = true;
			return db;
		} finally {
			// 释放占有
			mIsInitializing = false;
			if (success) {
				if (mDatabase != null) {
					try {
						mDatabase.close();
					} catch (Exception e) {
					}
				}
				mDatabase = db;
			} else {
				if (db != null)
					db.close();
			}
		}
	}

	/**
	 * 获取可读权限的数据库对象..
	 * 
	 * @return 数据库对象
	 */
	public synchronized SQLiteDatabase getReadableDatabase() {
		if (mDatabase != null && mDatabase.isOpen()) {
			// 已经获取过
			return mDatabase;
		}
		if (mIsInitializing) {
			throw new IllegalStateException("数据库已被占用getReadableDatabase()");
		}

		// 都是写获取写的数据库
		SQLiteDatabase db = null;

		try {
			db = getWritableDatabase();
			mDatabase = db;
		} catch (Exception e1) {
			try {
				mIsInitializing = true;
				String path = mDir + File.separator + mName;
				db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY);
				if (db.getVersion() != mNewVersion) {
					throw new SQLiteException("不能更新只读数据库的版本 from version " + db.getVersion() + " to " + mNewVersion + ": " + path);
				}
				onOpen(db);
				mDatabase = db;
				return mDatabase;
			} catch (SQLiteException e) {

			} finally {
				mIsInitializing = false;
				if (db != null && db != mDatabase)
					db.close();
			}
		}

		return mDatabase;
	}

	/**
	 * 数据库被打开.
	 * 
	 * @param db
	 *            被打开的数据库
	 */
	public void onOpen(SQLiteDatabase db) {
	}

	/**
	 * 数据库被关闭.
	 * 
	 */
	public synchronized void close() {
		if (mIsInitializing)
			throw new IllegalStateException("Closed during initialization");
		if (mDatabase != null && mDatabase.isOpen()) {
			mDatabase.close();
			mDatabase = null;
		}
	}

	/**
	 * 数据库被创建事件.
	 * 
	 * @param db
	 *            被创建的数据库
	 */
	public abstract void onCreate(SQLiteDatabase db);

	/**
	 * 数据库被重建.
	 * 
	 * @param db
	 *            被创建的数据库
	 * @param oldVersion
	 *            原来的数据库版本
	 * @param newVersion
	 *            新的数据库版本
	 */
	public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);

}
